package com.gasstation.domain

import java.util.Calendar
import java.util.Date

import com.gasstation.InventoryMidGrade
import com.gasstation.InventoryPremium
import com.gasstation.InventoryRegular

class GasUtil {
	static Date getLastDayOfMonth(Date date) {
		Calendar cal = Calendar.getInstance()
		cal.setTime(date)
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH))
		cal.set(Calendar.HOUR, 23)
		cal.set(Calendar.MINUTE, 59)
		cal.set(Calendar.SECOND, 59)
		return cal.getTime()
	}
	static Date getFirstDayOfMonth(Date date) {
		Calendar cal = Calendar.getInstance()
		cal.setTime(date)
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH))
		cal.set(Calendar.HOUR, 0)
		cal.set(Calendar.MINUTE, 0)
		cal.set(Calendar.SECOND, 0)
		return cal.getTime()
	}

	static Date getPreviousDate(int previous) {
		GregorianCalendar gc = new GregorianCalendar()
		gc.setTime(new Date())
		int dayBefore = gc.get(Calendar.DAY_OF_YEAR)
		gc.roll(Calendar.DAY_OF_YEAR, previous)
		int dayAfter = gc.get(Calendar.DAY_OF_YEAR)
		if(dayAfter > dayBefore) {
			gc.roll(Calendar.YEAR, previous)
		}
		gc.get(Calendar.DATE)
		return gc.getTime()
	}
	static Date getPreviousDate(int previous, Date transactionOn) {
		GregorianCalendar gc = new GregorianCalendar()
		gc.setTime(transactionOn)
		int dayBefore = gc.get(Calendar.DAY_OF_YEAR)
		gc.roll(Calendar.DAY_OF_YEAR, previous)
		int dayAfter = gc.get(Calendar.DAY_OF_YEAR)
		if(dayAfter > dayBefore) {
			gc.roll(Calendar.YEAR, previous)
		}
		gc.get(Calendar.DATE)
		gc.set(Calendar.HOUR, 23)
		gc.set(Calendar.MINUTE, 59)
		gc.set(Calendar.SECOND, 59)
		return gc.getTime()
	}
	static Date getEndDate(Date date) {
		Calendar cal = Calendar.getInstance()
		cal.setTime(date)
		cal.set(Calendar.HOUR, 23)
		cal.set(Calendar.MINUTE, 59)
		cal.set(Calendar.SECOND, 59)
		return cal.getTime()
	}
	static Date getStartDate(Date date) {
		Calendar cal = Calendar.getInstance()
		cal.setTime(date)
		cal.set(Calendar.HOUR_OF_DAY, 0)
		cal.set(Calendar.MINUTE, 0)
		cal.set(Calendar.SECOND, 0)
		return cal.getTime()
	}
	static void saveInventoryRegular(InventoryRegular inventoryRegularInstance){
		inventoryRegularInstance.calculateRegularCloseGallons()
		inventoryRegularInstance.calculateRegularAvgCost()
		inventoryRegularInstance.calculateRegularCost()
		inventoryRegularInstance.calculateRegularVariance()
		inventoryRegularInstance.save(flush: true, failOnError:true)
	}
	static void saveInventoryMidGrade(InventoryMidGrade inventoryMidGradeInstance){
		inventoryMidGradeInstance.calculateMidGradeCloseGallons()
		inventoryMidGradeInstance.calculateMidGradeAvgCost()
		inventoryMidGradeInstance.calculateMidGradeCost()
		inventoryMidGradeInstance.calculateMidGradeVariance()
		inventoryMidGradeInstance.save(flush: true, failOnError:true)
	}
	static void saveInventoryPremium(InventoryPremium inventoryPremiumInstance){
		inventoryPremiumInstance.calculatePremiumCloseGallons()
		inventoryPremiumInstance.calculatePremiumAvgCost()
		inventoryPremiumInstance.calculatePremiumCost()
		inventoryPremiumInstance.calculatePremiumVariance()
		inventoryPremiumInstance.save(flush: true, failOnError:true)
	}

	static updateSubsequentInventoryRegular(InventoryRegular inventoryRegularInstance, Date transactionOn) {
		double regularCloseGal = inventoryRegularInstance.regularCloseGallons
		double regularOpenInvCost = inventoryRegularInstance.regularOpenInvCost
		double regularPurchCost = inventoryRegularInstance.regularPurchasedCost
		double regularCost =  inventoryRegularInstance.regularCost
		def inventoryRegularList = InventoryRegular.findAllByTransactionOnGreaterThan(GasUtil.getPreviousDate(0, transactionOn))
		for (InventoryRegular inventoryRegular : inventoryRegularList) {
			inventoryRegular.regularOpenGallons = regularCloseGal
			inventoryRegular.regularOpenInvCost =regularOpenInvCost+regularPurchCost-regularCost
			GasUtil.saveInventoryRegular(inventoryRegular)
			regularCloseGal = inventoryRegular.regularCloseGallons
			regularOpenInvCost = inventoryRegular.regularOpenInvCost
			regularPurchCost = inventoryRegular.regularPurchasedCost
			regularCost =  inventoryRegular.regularCost
		}
	}
	static updateSubsequentInventoryMidGrade(InventoryMidGrade inventoryMidGradeInstance, Date transactionOn) {
		double midGradeCloseGal = inventoryMidGradeInstance.midGradeCloseGallons
		double midGradeOpenInvCost = inventoryMidGradeInstance.midGradeOpenInvCost
		double midGradePurchCost = inventoryMidGradeInstance.midGradePurchasedCost
		double midGradeCost =  inventoryMidGradeInstance.midGradeCost
		def inventoryMidGradeList = InventoryMidGrade.findAllByTransactionOnGreaterThan(GasUtil.getPreviousDate(0, transactionOn))
		for (InventoryMidGrade inventoryMidGrade : inventoryMidGradeList) {
			inventoryMidGrade.midGradeOpenGallons = midGradeCloseGal
			inventoryMidGrade.midGradeOpenInvCost =midGradeOpenInvCost+midGradePurchCost-midGradeCost
			GasUtil.saveInventoryMidGrade(inventoryMidGrade)
			midGradeCloseGal = inventoryMidGrade.midGradeCloseGallons
			midGradeOpenInvCost = inventoryMidGrade.midGradeOpenInvCost
			midGradePurchCost = inventoryMidGrade.midGradePurchasedCost
			midGradeCost =  inventoryMidGrade.midGradeCost
		}
	}
	static updateSubsequentInventoryPremium(InventoryPremium inventoryPremiumInstance, Date transactionOn) {
		double premiumCloseGal = inventoryPremiumInstance.premiumCloseGallons
		double premiumOpenInvCost = inventoryPremiumInstance.premiumOpenInvCost
		double premiumPurchCost = inventoryPremiumInstance.premiumPurchasedCost
		double premiumCost =  inventoryPremiumInstance.premiumCost
		def inventoryPremiumList = InventoryPremium.findAllByTransactionOnGreaterThan(GasUtil.getPreviousDate(0, transactionOn))
		for (InventoryPremium inventoryPremium : inventoryPremiumList) {
			inventoryPremium.premiumOpenGallons = premiumCloseGal
			inventoryPremium.premiumOpenInvCost =premiumOpenInvCost+premiumPurchCost-premiumCost
			GasUtil.saveInventoryPremium(inventoryPremium)
			premiumCloseGal = inventoryPremium.premiumCloseGallons
			premiumOpenInvCost = inventoryPremium.premiumOpenInvCost
			premiumPurchCost = inventoryPremium.premiumPurchasedCost
			premiumCost =  inventoryPremium.premiumCost
		}
	}
}
